import 'package:hive/hive.dart';
import '../../core/constants/api_constants.dart';
import '../models/anime_model.dart';

/// 本地数据源
/// 使用Hive进行数据缓存
class AnimeLocalDataSource {
  static const String _cacheBoxName = 'anime_cache';
  static const String _detailsBoxName = 'anime_details';
  static const String _metaBoxName = 'cache_meta';
  static const String _favoritesBoxName = 'favorites_cache'; // 收藏缓存

  late Box<List<dynamic>> _cacheBox;
  late Box<Map<dynamic, dynamic>> _detailsBox;
  late Box<Map<dynamic, dynamic>> _metaBox;
  late Box<Map<dynamic, dynamic>> _favoritesBox; // 收藏数据盒子

  /// 初始化本地存储
  Future<void> init() async {
    _cacheBox = await Hive.openBox<List<dynamic>>(_cacheBoxName);
    _detailsBox = await Hive.openBox<Map<dynamic, dynamic>>(_detailsBoxName);
    _metaBox = await Hive.openBox<Map<dynamic, dynamic>>(_metaBoxName);
    _favoritesBox = await Hive.openBox<Map<dynamic, dynamic>>(_favoritesBoxName);
  }

  /// 缓存动漫列表
  Future<void> cacheAnimeList(String key, List<AnimeModel> animeList) async {
    final jsonList = animeList.map((anime) => anime.toJson()).toList();
    await _cacheBox.put(key, jsonList);
    
    // 记录缓存时间
    await _metaBox.put(key, {
      'cached_at': DateTime.now().millisecondsSinceEpoch,
      'type': 'list',
      'count': animeList.length,
    });
  }

  /// 获取缓存的动漫列表，优先返回缓存数据
  Future<List<AnimeModel>> getCachedAnimeList(
    String key, {
    bool ignoreExpiry = false,
    bool preferCache = false, // 优先使用缓存
  }) async {
    if (!_cacheBox.containsKey(key)) {
      return [];
    }

    // 如果优先使用缓存，即使过期也返回
    if (preferCache || !await _isCacheExpired(key) || ignoreExpiry) {
      final jsonList = _cacheBox.get(key);
      if (jsonList == null) return [];

      try {
        return jsonList
            .cast<Map<String, dynamic>>()
            .map((json) => AnimeModel.fromJson(Map<String, dynamic>.from(json)))
            .toList();
      } catch (e) {
        // 数据格式错误，删除缓存
        await _removeCacheEntry(key);
        return [];
      }
    }

    // 缓存过期且不优先使用缓存
    await _removeCacheEntry(key);
    return [];
  }

  /// 缓存动漫详情
  Future<void> cacheAnimeDetails(AnimeModel anime) async {
    final key = 'anime_${anime.id}';
    await _detailsBox.put(key, anime.toJson());
    
    // 记录缓存时间
    await _metaBox.put(key, {
      'cached_at': DateTime.now().millisecondsSinceEpoch,
      'type': 'details',
      'anime_id': anime.id,
    });
  }

  /// 获取缓存的动漫详情
  Future<AnimeModel?> getCachedAnimeDetails(
    int animeId, {
    bool ignoreExpiry = false,
  }) async {
    final key = 'anime_$animeId';
    
    if (!_detailsBox.containsKey(key)) {
      return null;
    }

    // 检查缓存是否过期
    if (!ignoreExpiry && await _isCacheExpired(key)) {
      await _removeCacheEntry(key);
      return null;
    }

    final json = _detailsBox.get(key);
    if (json == null) return null;

    try {
      return AnimeModel.fromJson(Map<String, dynamic>.from(json));
    } catch (e) {
      // 数据格式错误，删除缓存
      await _removeCacheEntry(key);
      return null;
    }
  }

  /// 检查缓存是否过期
  Future<bool> _isCacheExpired(String key) async {
    final meta = _metaBox.get(key);
    if (meta == null) return true;

    final cachedAt = meta['cached_at'] as int?;
    if (cachedAt == null) return true;

    final cacheTime = DateTime.fromMillisecondsSinceEpoch(cachedAt);
    final now = DateTime.now();
    
    return now.difference(cacheTime) > ApiConstants.cacheValidDuration;
  }

  /// 删除缓存条目
  Future<void> _removeCacheEntry(String key) async {
    await _cacheBox.delete(key);
    await _detailsBox.delete(key);
    await _metaBox.delete(key);
  }

  /// 清除所有缓存
  Future<void> clearCache() async {
    await _cacheBox.clear();
    await _detailsBox.clear();
    await _metaBox.clear();
  }

  /// 获取缓存信息
  Future<Map<String, dynamic>> getCacheInfo() async {
    final totalEntries = _cacheBox.length + _detailsBox.length;
    final cacheSize = await _calculateCacheSize();
    final oldestEntry = await _getOldestCacheEntry();
    final newestEntry = await _getNewestCacheEntry();

    return {
      'total_entries': totalEntries,
      'list_entries': _cacheBox.length,
      'detail_entries': _detailsBox.length,
      'cache_size_mb': (cacheSize / (1024 * 1024)).toStringAsFixed(2),
      'oldest_entry': oldestEntry,
      'newest_entry': newestEntry,
      'cache_valid_duration_minutes': ApiConstants.cacheValidDuration.inMinutes,
    };
  }

  /// 计算缓存大小（简单估算）
  Future<int> _calculateCacheSize() async {
    int size = 0;
    
    // 估算列表缓存大小
    for (final key in _cacheBox.keys) {
      final value = _cacheBox.get(key);
      if (value != null) {
        size += value.toString().length * 2; // 粗略估算
      }
    }
    
    // 估算详情缓存大小
    for (final key in _detailsBox.keys) {
      final value = _detailsBox.get(key);
      if (value != null) {
        size += value.toString().length * 2; // 粗略估算
      }
    }
    
    return size;
  }

  /// 获取最旧的缓存条目
  Future<DateTime?> _getOldestCacheEntry() async {
    DateTime? oldest;
    
    for (final key in _metaBox.keys) {
      final meta = _metaBox.get(key);
      if (meta != null && meta['cached_at'] != null) {
        final cacheTime = DateTime.fromMillisecondsSinceEpoch(meta['cached_at']);
        if (oldest == null || cacheTime.isBefore(oldest)) {
          oldest = cacheTime;
        }
      }
    }
    
    return oldest;
  }

  /// 缓存排行榜数据
  Future<void> cacheRankingData(String rankingType, List<AnimeModel> animeList) async {
    final key = 'ranking_$rankingType';
    await cacheAnimeList(key, animeList);
  }

  /// 获取缓存的排行榜数据
  Future<List<AnimeModel>> getCachedRankingData(String rankingType, {bool preferCache = true}) async {
    final key = 'ranking_$rankingType';
    return await getCachedAnimeList(key, preferCache: preferCache);
  }

  /// 检查排行榜缓存是否存在且有效
  Future<bool> hasValidRankingCache(String rankingType) async {
    final key = 'ranking_$rankingType';
    return _cacheBox.containsKey(key) && !await _isCacheExpired(key);
  }

  /// 预加载排行榜缓存数据
  Future<Map<String, List<AnimeModel>>> preloadRankingCache() async {
    final rankingTypes = ['score', 'popularity', 'airing', 'favorites'];
    final result = <String, List<AnimeModel>>{};
    
    for (final type in rankingTypes) {
      final cachedData = await getCachedRankingData(type, preferCache: true);
      if (cachedData.isNotEmpty) {
        result[type] = cachedData;
      }
    }
    
    return result;
  }

  /// 获取最新的缓存条目
  Future<DateTime?> _getNewestCacheEntry() async {
    DateTime? newest;
    
    for (final key in _metaBox.keys) {
      final meta = _metaBox.get(key);
      if (meta != null && meta['cached_at'] != null) {
        final cacheTime = DateTime.fromMillisecondsSinceEpoch(meta['cached_at']);
        if (newest == null || cacheTime.isAfter(newest)) {
          newest = cacheTime;
        }
      }
    }
    
    return newest;
  }

  /// 清理过期缓存
  Future<int> cleanExpiredCache() async {
    int cleanedCount = 0;
    final keysToRemove = <String>[];
    
    for (final key in _metaBox.keys) {
      if (await _isCacheExpired(key.toString())) {
        keysToRemove.add(key.toString());
      }
    }
    
    for (final key in keysToRemove) {
      await _removeCacheEntry(key);
      cleanedCount++;
    }
    
    return cleanedCount;
  }

  /// 缓存收藏动漫列表
  Future<void> cacheFavoriteAnimeList(List<AnimeModel> animeList) async {
    final jsonList = animeList.map((anime) => anime.toJson()).toList();
    await _favoritesBox.put('favorite_list', {
      'data': jsonList,
      'cached_at': DateTime.now().millisecondsSinceEpoch,
      'count': animeList.length,
    });
  }

  /// 获取缓存的收藏动漫列表
  Future<List<AnimeModel>> getCachedFavoriteAnimeList() async {
    final cached = _favoritesBox.get('favorite_list');
    if (cached == null) return [];

    try {
      final data = cached['data'] as List?;
      if (data == null) return [];

      return data
          .cast<Map<String, dynamic>>()
          .map((json) => AnimeModel.fromJson(Map<String, dynamic>.from(json)))
          .toList();
    } catch (e) {
      // 数据格式错误，删除缓存
      await _favoritesBox.delete('favorite_list');
      return [];
    }
  }

  /// 添加单个收藏到缓存
  Future<void> addFavoriteToCache(AnimeModel anime) async {
    final currentList = await getCachedFavoriteAnimeList();
    
    // 检查是否已存在
    if (!currentList.any((item) => item.id == anime.id)) {
      currentList.add(anime);
      await cacheFavoriteAnimeList(currentList);
    }
  }

  /// 从缓存中移除收藏
  Future<void> removeFavoriteFromCache(int animeId) async {
    final currentList = await getCachedFavoriteAnimeList();
    currentList.removeWhere((item) => item.id == animeId);
    await cacheFavoriteAnimeList(currentList);
  }

  /// 检查是否在收藏缓存中
  Future<bool> isFavoriteInCache(int animeId) async {
    final favoriteList = await getCachedFavoriteAnimeList();
    return favoriteList.any((anime) => anime.id == animeId);
  }

  /// 获取首页数据缓存状态
  Future<Map<String, bool>> getHomePageCacheStatus() async {
    const homePageKeys = [
      'trending_anime_1_20',
      'upcoming_anime_1_5',
      'seasonal_anime_current_now_1',
      'recent_episodes_1_15',
    ];

    final status = <String, bool>{};
    for (final key in homePageKeys) {
      status[key] = _cacheBox.containsKey(key) && 
                   (await getCachedAnimeList(key, preferCache: true)).isNotEmpty;
    }
    return status;
  }

  /// 预热缓存 - 启动时使用
  Future<Map<String, List<AnimeModel>>> preloadHomePageCache() async {
    final result = <String, List<AnimeModel>>{};
    
    // 预加载首页关键数据
    final cacheKeys = {
      'trending': 'trending_anime_1_20',
      'upcoming': 'upcoming_anime_1_5',
      'seasonal': 'seasonal_anime_current_now_1',
      'recent': 'recent_episodes_1_15',
    };

    for (final entry in cacheKeys.entries) {
      final cached = await getCachedAnimeList(entry.value, preferCache: true);
      if (cached.isNotEmpty) {
        result[entry.key] = cached;
      }
    }

    return result;
  }
} 